#include "stdafx.hpp"
#include "ColligereOrangeCdXmlDataImporter.hpp"
#include "ColligereUtils.hpp"

///////////////////////////////////////////////
// ColligereOrangeCdXmlDataImporter
///////////////////////////////////////////////

void col::OrangeCdXmlDataImporter::Load ( const wxURI &rIn )
{
	wxASSERT ( rIn.GetScheme() == "file" );
	const wxString in_file ( wxURI ( rIn.GetPath() ).BuildUnescapedURI() );

	if ( !mInDoc.Load ( in_file ) )
	{
		throw DataImporterError ( rIn, _("Unable to load the input file.") );
	}
	if ( !IsValidOrangeCdXmlFile() )
	{
		throw DataImporterError ( rIn, _("The input file is not a valid OrangeCD XML-document." ) );
	}
}

wxUint32 col::OrangeCdXmlDataImporter::GetItemCount() const
{
	return XmlUtils::GetItemCount ( mInDoc, "Album" );
}

void col::OrangeCdXmlDataImporter::Import ( DatabaseInterfaceBase &rDest )
{
	DataImporterEvent evt_import_start ( COLLIGERE_EVT_IMPORT_START, rDest.GetId(), this );
	rDest.GetLayout()->GetEventHandler()->ProcessEvent ( evt_import_start );

	foreach ( const wxXmlNode *an, FindNodes ( mInDoc.GetRoot(), "Album") )
	{
		Artist artist ( GetNodeContent ( an, "Artist" ) );
		InitializeItemFromNode ( an, artist );
		Album album;
		InitializeItemFromNode ( an, album );

		foreach ( const wxXmlNode *node, FindNodes ( an, "Track") )
		{
			Track t;
			InitializeItemFromNode ( node, t );
			album.AddChild(t);
		}
		artist.AddChild ( album );
		rDest.GetHandler()->AddItem ( artist );

		DataImporterEvent evt_item_imported ( COLLIGERE_EVT_ITEM_IMPORTED, 
			rDest.GetId(), this, &album );
		rDest.GetLayout()->GetEventHandler()->ProcessEvent ( evt_item_imported );
	}
	DataImporterEvent evt_import_end ( COLLIGERE_EVT_IMPORT_END, rDest.GetId(), this );
	rDest.GetLayout()->GetEventHandler()->ProcessEvent ( evt_import_end );
}

void col::OrangeCdXmlDataImporter::InitializeItemFromNode
( const wxXmlNode *pNode, DatabaseItemBase &rItem ) const
{
	if ( Artist *artist = dynamic_cast < Artist * > ( &rItem ) )
	{
		artist->SetArtist ( GetNodeContent ( pNode, "Artist" ) );
		artist->SetCountry ( GetNodeContent ( pNode, "Country" ) );
	}
	else if ( Album *album = dynamic_cast < Album * > ( &rItem ) )
	{
		album->SetAlbum ( GetNodeContent ( pNode, "Title" ) ).
			SetYear ( GetNodeContent ( pNode, "Year") ).
			SetFormat ( GetNodeContent ( pNode, "Format") ).
			SetCondition ( GetNodeContent ( pNode, "Condition") ).
			SetStatus ( GetNodeContent ( pNode, "Status") ).
			SetExtInfo ( GetNodeContent ( pNode, "Comment") ).
			SetLabel ( GetNodeContent ( pNode, "Label") ).
			SetCatalogNum ( GetNodeContent ( pNode, "CatalogNo") );

			foreach ( const wxXmlNode *genre, FindNodes ( pNode, "Genre" ) )
			{
				const wxString genre_val ( album->GetGenre() );

				if ( genre_val.empty())
				{
					album->SetGenre ( GetNodeContent ( genre ) );
				}
				else 
				{
					album->SetGenre ( genre_val + wxString(" / ") + 
						GetNodeContent ( genre ) );
				}
			}
	}
	else if ( Track *track = dynamic_cast < Track * > ( &rItem ) )
	{
		const wxString title ( GetNodeContent ( FindNode ( pNode, "Title") ) );

		// OrangeCD inserts empty tracks to all added albums even
		// if the users doesn't want to list them.
		if ( !title.empty() )
		{
			track->SetTitle ( title );
			track->SetNum ( pNode->GetAttribute ( "Number", empty_string ) );
			track->SetLength ( pNode->GetAttribute ( "Time", empty_string ) );
		}
	}
}

bool col::OrangeCdXmlDataImporter::IsValidOrangeCdXmlFile() const
{
	return mInDoc.IsOk() && mInDoc.GetRoot()->GetName() == "Collection";
}